#include "Component.h"
#include "Container.h"
#include "RootContainer.h"
#include "Window.h"
#include "BackgroundGrabber.h"
#include "Cursor.h"

using namespace WONAPI;

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
static DWORD gComponentToolTipStartTime = 500;
static DWORD gComponentToolTipEndTime = 5000;


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
namespace WONAPI
{
class ComponentExtra
{
public:
	ColorSchemePtr mColorScheme;
	ComponentListenerPtr mListener;
	CursorPtr mDefaultCursor;
	BackgroundGrabber *mGrabBG;
	ComponentPtr mToolTip;
	bool mDontDoTip;

public:
	ComponentExtra();
	virtual ~ComponentExtra();

	static Cursor* GetDefaultCursor(Component *theComponent);
	static ComponentListener* GetListener(Component *theComponent);
	static BackgroundGrabber* GetGrabBG(Component *theComponent);
	static Component* GetToolTip(Component *theComponent);
	static bool GetDontDoToolTip(Component *theComponent);
};
} // namespace WONAPI

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
ComponentExtra::ComponentExtra()
{
	mGrabBG = NULL;
	mDontDoTip = false;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
ComponentExtra::~ComponentExtra()
{
	delete mGrabBG;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
Component::Component()
{
	mParent = NULL;
	mComponentFlags = 0;
//	mInvalidState = InvalidState_FullyInvalid;
	mInvalidState = InvalidState_Valid;
	mControlId = 0;
	mTimerFlags = 0;
	mFocusId = 0;
	mExtraStuff = NULL;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
Component::~Component()
{
	delete mExtraStuff;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::ApplyBackground(const Background &theBackground)
{
	if(theBackground.GetWantGrabBG())
		SetComponentFlags(ComponentFlag_GrabBG,true);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::AllocateExtraStuff()
{
	if(mExtraStuff==NULL)
		mExtraStuff = new ComponentExtra;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
BackgroundGrabber* Component::GetGrabBG() 
{ 
	if(mExtraStuff)
		return mExtraStuff->mGrabBG; 
	else
		return NULL;
}
	
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
Cursor* Component::GetDefaultCursor()
{
	if(mExtraStuff)
		return mExtraStuff->mDefaultCursor;
	else
		return NULL;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::SetListener(ComponentListener *theListener)
{
	AllocateExtraStuff();
	mExtraStuff->mListener = theListener;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::SetPos(int x, int y)
{
	mBounds.x = x;
	mBounds.y = y;

	PosChanged();
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::SetSize(int width, int height)
{
	if(width<0)
		width = 0;
	if(height<0)
		height = 0;

	if(width==mBounds.Width() && height==mBounds.Height())
		return;

	mBounds.width = width;
	mBounds.height = height;
	
	SizeChanged();
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::SetSizeAtLeast(int width, int height)
{
	if(width<mBounds.Width())
		width = mBounds.Width();

	if(height<mBounds.Height())
		height = mBounds.Height();

	if(width>mBounds.Width() || height>mBounds.Height())
		SetSize(width,height);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::SetPosSize(int x, int y, int width, int height)
{
	SetPos(x,y);
	SetSize(width,height);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::BringToTop()
{
	if(mParent!=NULL)
		mParent->BringToTop(this);
}
	
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::EnsureOnTopOf(Component *theSibling)
{
	if(mParent!=NULL)
		mParent->EnsureOnTopOf(theSibling,this);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::SetCursor(Cursor *theCursor)
{
	if(mParent!=NULL)
		mParent->SetCursor(theCursor);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::SetDefaultCursor(Cursor *theCursor)
{
	AllocateExtraStuff();
	mExtraStuff->mDefaultCursor = theCursor;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::MouseEnter(int x, int y)
{
	if(mExtraStuff)
		SetCursor(mExtraStuff->mDefaultCursor);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::MouseExit()
{
	if(mExtraStuff)
	{
		if(mExtraStuff->mToolTip.get()!=NULL)
		{
			mExtraStuff->mDontDoTip = false;
			GetWindow()->EndPopup(mExtraStuff->mToolTip);
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::MouseHover(DWORD theElapsed)
{
	if(!mExtraStuff || mExtraStuff->mToolTip.get()==NULL)
		return;

	if(theElapsed >= gComponentToolTipStartTime && !mExtraStuff->mDontDoTip)
	{
		Window *aWindow = GetWindow();
		int x = aWindow->GetMouseX() + 15;
		int y = aWindow->GetMouseY() + 15;
		aWindow->DoPopup(PopupParams(mExtraStuff->mToolTip,PopupFlag_StandardTip,this,x,y));
		mExtraStuff->mDontDoTip = true;
	}
	else if(theElapsed >= gComponentToolTipStartTime + gComponentToolTipEndTime)
		GetWindow()->EndPopup(mExtraStuff->mToolTip);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::SetToolTip(Component *theTip)
{
	AllocateExtraStuff();
	mExtraStuff->mToolTip = theTip;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::SetToolTipTimes(DWORD theStartTime, DWORD theEndTime)
{
	gComponentToolTipStartTime = theStartTime;
	gComponentToolTipEndTime = theEndTime;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
bool Component::CheckGrabBG()
{
	if(ComponentFlagSet(ComponentFlag_GrabBG | ComponentFlag_Translucent))
	{
		AllocateExtraStuff();
		if(mExtraStuff->mGrabBG == NULL)
			mExtraStuff->mGrabBG = new BackgroundGrabber;

		return true;
	}
	else
		return false;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::SizeChanged()
{
	if(CheckGrabBG())
		mExtraStuff->mGrabBG->SizeChanged(this);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::PosChanged()
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::GetDesiredSize(int &width, int &height)
{
	width = 20;
	height = 20;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::SetDesiredSize(int theExtraWidth, int theExtraHeight)
{
	int aWidth = 0, aHeight = 0;
	GetDesiredSize(aWidth,aHeight);
	SetSize(aWidth+theExtraWidth,aHeight+theExtraHeight);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::SetDesiredWidth(int theExtraWidth)
{
	int aWidth = 0, aHeight = 0;
	GetDesiredSize(aWidth,aHeight);
	SetSize(aWidth+theExtraWidth,Height());
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::SetDesiredHeight(int theExtraHeight)
{
	int aWidth = 0, aHeight = 0;
	GetDesiredSize(aWidth,aHeight);
	SetSize(Width(),aHeight+theExtraHeight);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
bool Component::NeedPrePaint()
{
	if(!IsInvalid())
		return false;

	if(IsVisible())
		return true;

	return (CheckGrabBG() && mExtraStuff->mGrabBG->NeedDrawBG());
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::SetTranslucentColor(int theColor, int theLevel)
{
	SetComponentFlags(ComponentFlag_Translucent,true);
	if(!CheckGrabBG())
		return;

	mExtraStuff->mGrabBG->SetTranslucentColor(theColor,theLevel);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::PrePaint(Graphics &g)
{
	if(CheckGrabBG())
		mExtraStuff->mGrabBG->PrePaint(this,g);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::Paint(Graphics &g)
{
	if(CheckGrabBG())
		mExtraStuff->mGrabBG->Paint(this,g);

	mInvalidState = InvalidState_Valid;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
bool Component::WantInput(int x, int y)
{
	return IsVisible() && !ComponentFlagSet(ComponentFlag_NoInput);
}


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
bool Component::Contains(int x, int y)
{
	return mBounds.Contains(x,y);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
bool Component::Intersects(Component *theComponent)
{
	return mBounds.Intersects(theComponent->mBounds);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::InvalidateRect(WONRectangle &theRect)
{
	if(mParent!=NULL)
	{
		theRect.x += mBounds.Left();
		theRect.y += mBounds.Top();
		mParent->InvalidateRect(theRect);
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::Invalidate()
{			
	if(IsSelfInvalid())
		return;

	WONRectangle r(0, 0, mBounds.Width(), mBounds.Height());
	InvalidateRect(r);

	if (mParent!=NULL)
		mParent->InvalidateUp(this);

	InvalidateDown();
	mInvalidState = InvalidState_SelfInvalid;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::InvalidateFully()
{
	Invalidate();
	mInvalidState = InvalidState_FullyInvalid;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::InvalidateDown()
{
	mInvalidState = InvalidState_FullyInvalid;	
	if(CheckGrabBG())
	{
		Container *aParent = GetParent();
/*		if(aParent!=NULL && aParent->IsFullyInvalid())
			mGrabBG->Clear();
		else
			mGrabBG->Invalidate(this);*/
		mExtraStuff->mGrabBG->Invalidate(this);
		RootContainer *aRoot = GetRoot();
		if(aRoot!=NULL)
			aRoot->AddBG(mExtraStuff->mGrabBG);
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::AddedToParent()
{
	if(HasFocus())
	{
		if(!WantFocus())
			LostFocus();
		else
			mParent->ChildRequestFocus(this);
	}

	if(WantTimer())
		mParent->ChildRequestTimer(this);

	if(mParent->IsVisibleUpToRoot() && IsVisible())
		NotifyRootVisibilityChange(true);

	mInvalidState = InvalidState_Valid;
	Invalidate();

//	if(GetRoot()!=NULL)
//		AddedToRoot();
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::AddedToRoot()
{
	if(CheckGrabBG())
		mExtraStuff->mGrabBG->Clear();
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
Component* Component::GetNextSibling(bool forward, bool wrap)
{
	if(mParent==NULL)
		return NULL;

	ChildList::iterator anItr = mChildListItr;

	if(forward)
	{
		++anItr;
		if(anItr==mParent->mChildList.end())
		{
			if(!wrap)
				return NULL;
			else
				return mParent->mChildList.front();
		}
	}
	else
	{
		if(anItr==mParent->mChildList.begin())
		{
			if(!wrap)
				return NULL;
			else
				return mParent->mChildList.back();
		}
		else
			--anItr;
	}

	return *anItr;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::BroadcastEvent(int theEvent, bool sendNow)
{
	ComponentEvent* anEvent = new ComponentEvent(this,theEvent);
	anEvent->mBroadcast = true;
	FireEvent(anEvent, sendNow);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::BroadcastEvent(ComponentEvent *theEvent, bool sendNow)
{
	theEvent->mBroadcast = true;
	FireEvent(theEvent, sendNow);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::BroadcastEventDownPrv(ComponentEvent *theEvent)
{
	HandleComponentEvent(theEvent);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::BroadcastEventDown(ComponentEvent *theEvent)
{
	ComponentEventPtr anEvent = theEvent;
	theEvent->mBroadcast = true;
	BroadcastEventDownPrv(theEvent);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::SubscribeToBroadcast(bool subscribe)
{
	GetWindow()->GetWindowManager()->SubscribeToBroadcast(this,subscribe);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::FireEvent(int theEvent, bool sendNow)
{
//	DeliverComponentEvent(this, theEvent);
	FireEvent(new ComponentEvent(this, theEvent), sendNow);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::FireEvent(ComponentEvent *theEvent, bool sendNow)
{
	Window *aWindow = GetMyWindow();
	if(aWindow==NULL || !aWindow->IsOpen())
	{
		ComponentEventPtr anEvent = theEvent; // may not have an auto reference anywhere
		return;
	}

	if(theEvent->mComponent==NULL)
		theEvent->SetComponent(this);

	if(sendNow)
	{
		ComponentEventPtr anEvent = theEvent; // may not have an auto reference anywhere
		if(theEvent->mBroadcast)
			aWindow->GetWindowManager()->BroadcastEvent(theEvent);
		else
			DeliverComponentEvent(theEvent);
	}
	else
		aWindow->PostEvent(theEvent);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::DeliverComponentEvent(ComponentEvent *theEvent)
{
	if(theEvent->mBroadcast)
		return;

	if(mExtraStuff && mExtraStuff->mListener.get()!=NULL)
		mExtraStuff->mListener->HandleComponentEvent(theEvent);
	else if(mParent!=NULL)
		mParent->HandleComponentEvent(theEvent);
	else
	{
		Window *aWindow = GetWindow();
		if(aWindow!=NULL)
		{
			aWindow = aWindow->GetParent();
			if(aWindow!=NULL && aWindow->GetRoot()!=NULL)
				aWindow->GetRoot()->DeliverComponentEvent(theEvent);
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::HandleComponentEvent(ComponentEvent *theEvent)
{
	DeliverComponentEvent(theEvent);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::SetComponentFlags(int theFlags, bool on)
{
	if(on)
		mComponentFlags |= theFlags;
	else
		mComponentFlags &= ~theFlags;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::NotifyRootVisibilityChange(bool isVisible)
{
	SetComponentFlags(ComponentFlag_IsVisibleToRoot,isVisible);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::SetVisible(bool isVisible)
{
	if(isVisible==IsVisible())
		return;

	SetComponentFlags(ComponentFlag_Invisible,!isVisible);
	mInvalidState = InvalidState_Valid;
	if(mParent!=NULL)
		mParent->ChildChanged(this);

	Invalidate();

	NotifyRootVisibilityChange(isVisible);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
bool Component::IsVisibleUpToRoot()
{
	return ComponentFlagSet(ComponentFlag_IsVisibleToRoot);
/*	if(!IsVisible())
		return false;
	else if(GetParent()==NULL)
		return this==GetRoot();
	else
		return GetParent()->IsVisibleUpToRoot();*/
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::Enable(bool isEnabled)
{
	if(isEnabled==!Disabled())
		return;

	SetComponentFlags(ComponentFlag_Disabled,!isEnabled);	
	EnableHook(isEnabled);

	if(mParent!=NULL)
		mParent->ChildChanged(this);

	Invalidate();
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::EnableControls(const ControlIdSet &theSet, bool enable)
{
	if(mControlId!=0 && theSet.HasId(mControlId))
		Enable(enable);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::ChildToRoot(int &x, int &y)
{
	x+=mBounds.Left();
	y+=mBounds.Top();
	if(mParent!=NULL)
		mParent->ChildToRoot(x,y);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::RootToChild(int &x, int &y)
{
	x-=mBounds.Left();
	y-=mBounds.Top();
	if(mParent!=NULL)
		mParent->RootToChild(x,y);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::GetMousePos(int &x, int &y)
{
	Window *aWindow = GetWindow();
	x = aWindow->GetMouseX();
	y = aWindow->GetMouseY();
	RootToChild(x,y);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
int Component::GetKeyMod()
{
	Window *aWindow = GetWindow();
	return aWindow->GetKeyMod();
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
bool Component::CheckDoubleClick(MouseButton theButton)
{
	Window *aWindow = GetWindow();
	return aWindow->CheckDoubleClick(theButton);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::RequestTimer(bool on)
{
	bool oldWantTimer = WantTimer();

	if(on)
		mTimerFlags |= TimerFlag_IWant;
	else
		mTimerFlags &= ~TimerFlag_IWant;

	if(WantTimer()==oldWantTimer)
		return;

//	SetComponentFlags(ComponentFlag_WantTimer, on);
	if(mParent!=NULL)
		mParent->ChildRequestTimer(this);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
bool Component::WantFocus()
{
	if(!ComponentFlagSet(ComponentFlag_WantFocus))
		return false;

	if(!IsVisible() || Disabled())
		return false;

	if(mParent!=NULL && mParent->IsModal() && !ComponentFlagSet(ComponentFlag_AllowModalInput))
		return false;

	return true;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
bool Component::TakeTabFocus(bool forward, bool init)
{
	if(!init)
		return false;

	if(ComponentFlagSet(ComponentFlag_WantTabFocus) && WantFocus())
	{
		RequestFocus();
		return true;
	}
	else
		return false;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::RequestFocus()
{
	if(HasFocus() || !WantFocus())
		return;

	if(mParent==NULL)
		GotFocus();
	else
		mParent->ChildRequestFocus(this);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::GotFocus()
{
	SetComponentFlags(ComponentFlag_HasFocus, true);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::LostFocus()
{
	SetComponentFlags(ComponentFlag_HasFocus, false);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
RootContainer* Component::GetRoot()
{
	if(mParent==NULL)
	{
		RootContainer *aContainer = dynamic_cast<RootContainer*>(this);
		if(aContainer!=NULL)
			return aContainer;
		else
			return NULL;
	}
	else
		return mParent->GetRoot();
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
WONAPI::Window* Component::GetWindow()
{
	RootContainer *aRoot = GetRoot();
	if(aRoot!=NULL)
		return aRoot->GetWindow();
	else
		return WONAPI::Window::GetDefaultWindow();
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
Window* Component::GetMyWindow()
{
	RootContainer *aRoot = GetRoot();
	if(aRoot!=NULL)
		return aRoot->GetWindow();
	else
		return NULL;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
ColorScheme* Component::GetOwnColorScheme()
{
	if(mExtraStuff)
		return mExtraStuff->mColorScheme;
	else
		return NULL;
}
	
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
ColorScheme* Component::GetColorScheme()
{
	if(mExtraStuff && mExtraStuff->mColorScheme.get())
		return mExtraStuff->mColorScheme;
	else if(mParent)
		return mParent->GetColorScheme();
	else
	{
		Window *aWindow = GetWindow();
		return aWindow->GetWindowManager()->GetColorScheme();
	}	
}
	
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Component::SetColorScheme(ColorScheme* theColorScheme)
{
	AllocateExtraStuff();
	mExtraStuff->mColorScheme = theColorScheme;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
FontPtr Component::GetFont(const FontDescriptor &theDescriptor)
{
	Window *aWindow = GetWindow();
	return aWindow->GetFont(theDescriptor);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
Font* Component::GetFontMod(Font *theBaseFont, int theStyle, int theSize)
{
	FontDescriptor aDesc = theBaseFont->GetDescriptor();
	aDesc.mStyle = theStyle;

	if(theSize>0)
		aDesc.mSize = theSize;

	return GetFont(aDesc);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
Font* Component::GetDefaultFont()
{
	Window *aWindow = GetWindow();
	return aWindow->GetWindowManager()->GetDefaultFont();
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
WONAPI::Font* Component::GetNamedFont(const std::string &theName)
{
	Window *aWindow = GetWindow();
	return aWindow->GetWindowManager()->GetNamedFont(theName);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
Font* Component::GetDefaultFontMod(int theStyle, int theSize)
{
	Window *aWindow = GetWindow();
	return aWindow->GetWindowManager()->GetDefaultFontMod(theStyle,theSize);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
Font* Component::GetNamedFontMod(const std::string &theName, int theStyle, int theSize)
{
	Window *aWindow = GetWindow();
	return aWindow->GetWindowManager()->GetNamedFontMod(theName,theStyle,theSize);
}

